/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * WidokGrafu.java
 *
 * Created on 2011-06-09, 12:57:50
 */
package formatki;

import graf.Wierzcholek;
import graf.WierzcholekPlusPlus;
import graf.DefUse;
import graf.Definicja;
import graf.Uzycie;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
 *
 * @author marek
 */
public class WidokGrafu extends javax.swing.JPanel implements MouseListener, MouseMotionListener {

    private int nextX = 30;
    private int nextY = 30;
    private int r = 15;
    private int przejscie = 50;
    private boolean przesunY = false;
    private Wierzcholek stanZaznaczony;
    private Formatka formatka;

    public int getNextX() {
        int x = nextX;
        if (nextX + przejscie > this.getWidth() - r) {
            nextX = 30;
            przesunY = true;
        } else {
            nextX += przejscie;
        }
        return x;
    }

    public int getNextY() {
        int y = nextY;
        if (przesunY) {
            nextY += przejscie;
            przesunY = false;
        }
        return y;
    }

    public int getR() {
        return r;
    }

    public void paint(Graphics g) {
        if (formatka.getGraf() == null) {
            return;
        }
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());

        for (Wierzcholek w : formatka.getGraf().getWierzcholki()) {
            for (WierzcholekPlusPlus ww : w.getSasiedzi()) {
                rysujKrawedz(w, ww.getWierzcholek(), g);
            }
        }

        for (Wierzcholek w : formatka.getGraf().getWierzcholki()) {
            rysujWierzcholek(w, g);
        }

    }

    public void rysujWierzcholek(Wierzcholek wierzcholek, Graphics g) {
        if (formatka.getGraf().isPoczatkowy(wierzcholek)
                && formatka.getGraf().isKoncowy(wierzcholek)) {
            g.setColor(Color.YELLOW);
        } else if (formatka.getGraf().isPoczatkowy(wierzcholek)) {
            g.setColor(Color.BLUE);
        } else if (formatka.getGraf().isKoncowy(wierzcholek)) {
            g.setColor(Color.GREEN);
        } else {
            g.setColor(Color.RED);
        }
        g.fillOval(wierzcholek.getX() - r, wierzcholek.getY() - r, 2 * r, 2 * r);
        g.setColor(Color.black);
        g.drawString(new Integer(wierzcholek.getNumer()).toString(), wierzcholek.getX() - r / 20, wierzcholek.getY() + r / 6);
        //wypisanie uzyc
        String use = "";
        String def = "";
        boolean przecinek = false;
        boolean przecinek2 = false;
        for (int i = 0; i < wierzcholek.getDefUse().size(); ++i) {
            if (wierzcholek.getDefUse().get(i) instanceof Uzycie) {
                if (przecinek) {
                    use += ", ";
                } else {
                    use = "use(";
                }
                use += wierzcholek.getDefUse().get(i).getZmienna();
                przecinek = true;
            } else if (wierzcholek.getDefUse().get(i) instanceof Definicja) {
                if (przecinek2) {
                    def += ", ";
                } else {
                    def = "def(";
                }
                def += wierzcholek.getDefUse().get(i).getZmienna();
                przecinek2 = true;
            }

        }
        if (!use.equals("")) {
            use += ")";
        }
        g.drawString(use, wierzcholek.getX(), wierzcholek.getY() + 2 * r);
        //wypisanie definicji

        if (!def.equals("")) {
            def += ")";
        }
        g.drawString(def, wierzcholek.getX(), wierzcholek.getY() + 3 * r);
    }

    public void rysujKrawedz(Wierzcholek pocz, Wierzcholek kon, Graphics g) {
        g.setColor(Color.black);
        //wypisanie uzyc
        String use = "";
        String def = "";
        boolean przecinek = false;
        boolean przecinek2 = false;
        for (WierzcholekPlusPlus wpp : pocz.getSasiedzi()) {
            if (wpp.getWierzcholek().equals(kon)) {
                for (DefUse du : wpp.getDefUse()) {
                    if (du instanceof Uzycie) {
                        if (przecinek) {
                            use += ", ";
                        } else {
                            use = "use(";
                        }
                        use += du.getZmienna();
                        przecinek = true;
                    } else if (du instanceof Definicja) {
                        if (przecinek2) {
                            def += ", ";
                        } else {
                            def = "def(";
                        }
                        def += du.getZmienna();
                        przecinek2 = true;
                    }
                }
            }
        }
        if (!use.equals("")) {
            use += ")";
        }

        //wypisanie definicji
        if (!def.equals("")) {
            def += ")";
        }
        if (pocz.equals(kon)) {
            int poczX = pocz.getX() + (int) (r / Math.sqrt(2.0));
            int poczY = pocz.getY() - (int) (r / Math.sqrt(2.0));
            int konX = kon.getX() - (int) (r / Math.sqrt(2.0));
            int konY = kon.getY() - (int) (r / Math.sqrt(2.0));
            g.drawLine(poczX, poczY, poczX, poczY - 2 * r);
            g.drawLine(poczX, poczY - 2 * r, konX, konY - 2 * r);
            g.drawLine(konX, konY - 2 * r, konX, konY);

            g.drawString(use, pocz.getX(), pocz.getY() - 4 * r);
            g.drawString(def, pocz.getX(), pocz.getY() - 3 * r);

        } else {
            g.drawLine(pocz.getX(), pocz.getY(),
                    kon.getX(), kon.getY());
            int dl = (int) Math.sqrt((kon.getX() - pocz.getX()) * (kon.getX() - pocz.getX())
                    + (kon.getY() - pocz.getY()) * (kon.getY() - pocz.getY()));
//            System.out.println(dl);
            int wektX = (kon.getX() - pocz.getX());
//            System.out.println("x" + wektX);
            int wektY = (kon.getY() - pocz.getY());

            g.fillRect((int) (kon.getX() - (r * wektX) / dl - 3 * (Math.signum(wektX))), (int) (kon.getY() - (r * wektY) / dl - 3 * Math.signum(wektY)), 5, 5);


            g.drawString(use, (pocz.getX() + kon.getX()) / 2 - r, (pocz.getY() + kon.getY()) / 2);
            g.drawString(def, (pocz.getX() + kon.getX()) / 2 - r, (pocz.getY() + kon.getY()) / 2 - r);

        }
    }

    /** Creates new form WidokGrafu */
    public WidokGrafu() {
        initComponents();
    }

    public WidokGrafu(Formatka aThis) {
        formatka = aThis;
        initComponents();
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private boolean nalezy(int x, int y, int x0, int y0) {
        if ((x - x0) * (x - x0) + (y - y0) * (y - y0) <= r * r) {
            return true;
        } else {
            return false;
        }
    }

    private Wierzcholek znajdz(int x, int y) {
        for (Wierzcholek w : formatka.getGraf().getWierzcholki()) {
            if (nalezy(x, y, w.getX(), w.getY())) {
                return w;
            }
        }
        return null;
    }

    public void mousePressed(MouseEvent e) {
        Wierzcholek w = znajdz(e.getX(), e.getY());
        if (w != null) {
            stanZaznaczony = w;
        }
    }

    public void mouseReleased(MouseEvent e) {
        stanZaznaczony = null;
    }

    public void mouseDragged(MouseEvent e) {
        if (stanZaznaczony != null) {
            if (e.getX() + r < this.getWidth() && e.getX() - r > 0) {
                stanZaznaczony.setX(e.getX());
            }
            if (e.getY() + r < this.getHeight() && e.getY() - r > 0) {
                stanZaznaczony.setY(e.getY());
            }
            paint(getGraphics());
        }
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseMoved(MouseEvent e) {
    }

    void reset() {
        nextX = 30;
        nextY = 30;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}
